import type { Chart, FinancialDataPoint } from "chart.js";
import type { IndicatorActionWrap, IndicatorGroupKey, Kline, KlineFlat, LSMAv, MAv, MaLineGroupKey, ValueWrapper } from './bindings';
import 'chartjs-adapter-luxon'; // This line imports the adapter
import { DateTime } from 'luxon';
import { formatDate } from "$lib";

export const GLOBAL_CHART_DATA = {
    datasets: [
        {
            label: 'Volume',
            type: 'bar' as const,
            data: [],
            yAxisID: 'y-volume',
            backgroundColor: (context: any) => calculateVolumeBackgroundColor(context),
            borderColor: (context: any) => calculateVolumeBorderColor(context),
            borderWidth: 1,
            hoverBorderWidth: 6,
        }, {
            label: 'TradeOrder',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-volume',
            backgroundColor: 'rgb(255, 99, 132)',
            pointStyle: 'triangle',
        }, {
            label: 'Price',
            type: 'candlestick' as const,
            data: [],
            yAxisID: 'y-price',
            backgroundColors: {
                up: 'rgba(255, 0, 0, 0.1)', // Semi-transparent red for price up
                down: 'rgba(0, 255, 0, 0.1)', // Semi-transparent green for price down
                unchanged: 'rgba(128, 128, 128, 0.1)', // Semi-transparent gray for unchanged
            },
            borderColors: {
                up: '#FF0000', // Red border for price up
                down: '#00FF00', // Green border for price down
                unchanged: 'gray', // Optional border color for unchanged
            },
            borderWidth: 1,
            hoverBorderWidth: 6,
        }, {
            label: 'maline_0',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(255, 0, 0, 0.5)',
            backgroundColor: 'rgba(255, 0, 0, 0.5)',
            hoverBorderColor: 'rgba(255, 0, 0, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_1',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(0, 255, 0, 0.5)',
            backgroundColor: 'rgba(0, 255, 0, 0.5)',
            hoverBorderColor: 'rgba(0, 255, 0, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_2',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(0, 0, 255, 0.5)',
            backgroundColor: 'rgba(0, 0, 255, 0.5)',
            hoverBorderColor: 'rgba(0, 0, 255, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_3',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(255, 128, 0, 0.5)',
            backgroundColor: 'rgba(255, 128, 0, 0.5)',
            hoverBorderColor: 'rgba(255, 128, 0, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_4',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(255, 0, 128, 0.5)',
            backgroundColor: 'rgba(255, 0, 128, 0.5)',
            hoverBorderColor: 'rgba(255, 0, 128, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_5',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(0, 255, 128, 0.5)',
            backgroundColor: 'rgba(0, 255, 128, 0.5)',
            hoverBorderColor: 'rgba(0, 255, 128, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_6',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(0, 128, 255, 0.5)',
            backgroundColor: 'rgba(0, 128, 255, 0.5)',
            hoverBorderColor: 'rgba(0, 128, 255, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_7',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(128, 255, 0, 0.5)',
            backgroundColor: 'rgba(128, 255, 0, 0.5)',
            hoverBorderColor: 'rgba(128, 255, 0, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'maline_8',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(128, 0, 255, 0.5)',
            backgroundColor: 'rgba(128, 0, 255, 0.5)',
            hoverBorderColor: 'rgba(128, 0, 255, 0.5)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_0',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 1,
            borderColor: 'rgba(255, 0, 0, 0.9)',
            backgroundColor: 'rgba(255, 0, 0, 0.)',
            hoverBorderColor: 'rgba(255, 0, 0, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_1',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 1,
            borderColor: 'rgba(0, 255, 0, 0.9)',
            backgroundColor: 'rgba(0, 255, 0, 0.9)',
            hoverBorderColor: 'rgba(0, 255, 0, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_2',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 1,
            borderColor: 'rgba(0, 0, 255, 0.9)',
            backgroundColor: 'rgba(0, 0, 255, 0.9)',
            hoverBorderColor: 'rgba(0, 0, 255, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_3',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(255, 128, 0, 0.9)',
            backgroundColor: 'rgba(255, 128, 0, 0.9)',
            hoverBorderColor: 'rgba(255, 128, 0, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_4',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(255, 0, 128, 0.9)',
            backgroundColor: 'rgba(255, 0, 128, 0.9)',
            hoverBorderColor: 'rgba(255, 0, 128, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_5',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(0, 255, 128, 0.9)',
            backgroundColor: 'rgba(0, 255, 128, 0.9)',
            hoverBorderColor: 'rgba(0, 255, 128, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_6',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(0, 128, 255, 0.9)',
            backgroundColor: 'rgba(0, 128, 255, 0.9)',
            hoverBorderColor: 'rgba(0, 128, 255, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_7',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(128, 255, 0, 0.9)',
            backgroundColor: 'rgba(128, 255, 0, 0.9)',
            hoverBorderColor: 'rgba(128, 255, 0, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'lsma_8',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderWidth: 2,
            pointRadius: 0,
            borderColor: 'rgba(128, 0, 255, 0.9)',
            backgroundColor: 'rgba(128, 0, 255, 0.9)',
            hoverBorderColor: 'rgba(128, 0, 255, 0.9)',
            hoverBorderWidth: 6,
        }, {
            label: 'trend_lines',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-price',
            borderDash: [5, 5],
            borderWidth: 1,
            pointRadius: 0,
            borderColor: 'rgba(0, 255, 128, 0.5)',
            backgroundColor: 'rgba(0, 255, 128, 0.5)',
            hoverBorderWidth: 6,
        },

        // adx
        {
            label: 'adx_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-adx',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'adx_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-adx',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'adx_adx',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-adx',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(255, 0, 0)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'adx_di_plus',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-adx',
            backgroundColor: 'rgba(0, 255, 0, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(0, 255, 0)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'adx_di_minus',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-adx',
            backgroundColor: 'rgba(0, 0, 255, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(0, 0, 255)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // aroon
        {
            label: 'aroon_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-aroon',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'aroon_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-aroon',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'aroon_signal2',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-aroon',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'rect'
        }, {
            label: 'aroon_up',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-aroon',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(255, 0, 255)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'aroon_down',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-aroon',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(255, 0, 0)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        // aso
        {
            label: 'aso_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-aso',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'aso_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-aso',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'aso_dif',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-aso',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // boll
        {
            label: 'boll_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-boll',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'boll_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-boll',
            backgroundColor: 'rgba(128, 0, 128, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(128, 0, 128)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        {
            label: 'boll_middle',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-boll',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(255, 0, 255)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        {
            label: 'boll_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-boll',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright purple for Bollinger Bands line
            borderColor: 'rgb(255, 0, 0)', // Solid bright purple for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // cci
        {
            label: 'cci_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cci',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cci_oscillator',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cci',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'cko_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cko',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cko_oscillator',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cko',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        // cks
        {
            label: 'cks_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cks',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cks_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cks',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'cks_stop_long',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cks',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'cks_source',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cks',
            backgroundColor: 'rgba(0, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'cks_stop_short',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cks',
            backgroundColor: 'rgba(0, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'cmf_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cmf',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cmf_main',
            type: 'bar',
            data: [],
            yAxisID: 'y-cmf',
            backgroundColor: 'rgba(255, 165, 0, 0.3)', // Bright orange for CMF bars
            borderColor: 'rgb(255, 165, 0)', // Solid bright orange for borders
            borderWidth: 1,
        },

        {
            label: 'cmo_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cmo',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cmo_oscillator',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cmo',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'cpc_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cpc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'cpc_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cpc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'cpc_signal2',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-cpc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'rect',
        }, {
            label: 'cpc_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cpc',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'cpc_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-cpc',
            backgroundColor: 'rgba(0, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // dcc
        {
            label: 'dcc_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-dcc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'dcc_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-dcc',
            backgroundColor: 'rgba(0, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'dcc_middle',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-dcc',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'dcc_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-dcc',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'dpo_dpo',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-dpo',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // efi
        {
            label: 'efi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-efi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'efi_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-efi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // eom
        {
            label: 'eom_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-eom',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'eom_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-eom',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'evl_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-evl',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'evl_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-evl',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'evl_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-evl',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'evl_source2',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-evl',
            backgroundColor: 'rgba(0, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'ftf_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-ftf',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'ftf_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-ftf',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'ftf_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ftf',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'ftf_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ftf',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // hma
        {
            label: 'hma_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-hma',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'hma_hma',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-hma',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'ikc_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'ikc_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'ikc_tenkan',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'ikc_kijun',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: 'rgba(0, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'ikc_spana',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'ikc_spanb',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-ikc',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'kama_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kama',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'kama_kama',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kama',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'kdj_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kdj',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'kdj_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kdj',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'kdj_signal2',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kdj',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'rect'
        }, {
            label: 'kdj_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kdj',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'kdj_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kdj',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'knc_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-knc',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'knc_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-knc',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'knc_source',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-knc',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'knc_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-knc',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'kst_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kst',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'kst_kst',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kst',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'kst_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kst',
            backgroundColor: 'rgba(0, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(0, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },


        {
            label: 'kvo_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kvo',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'kvo_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-kvo',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'kvo_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kvo',
            backgroundColor: 'rgba(0, 0, 255, 0.3)', // Bright blue for KVO line
            borderColor: 'rgb(0, 0, 255)', // Solid bright blue for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'kvo_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-kvo',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright blue for KVO line
            borderColor: 'rgb(255, 0, 0)', // Solid bright blue for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },


        {
            label: 'macd_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-macd',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'macd_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-macd',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'macd_bar',
            type: 'bar' as const,
            data: [],
            yAxisID: 'y-macd',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright yellow for MACD bars
            borderColor: 'rgb(255, 255, 0)', // Solid bright yellow for borders
            borderWidth: 1,
        }, {
            label: 'macd_macd',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-macd',
            backgroundColor: 'rgba(0, 0, 255, 0.3)', // Bright yellow for MACD bars
            borderColor: 'rgb(0, 0, 255)', // Solid bright yellow for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'macd_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-macd',
            backgroundColor: 'rgba(255, 0, 0, 0.3)', // Bright yellow for MACD bars
            borderColor: 'rgb(255, 0, 0)', // Solid bright yellow for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
        // mfi
        {
            label: 'mfi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-mfi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'mfi_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-mfi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'mfi_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-mfi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'mfi_mfi',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-mfi',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'mfi_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-mfi',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },


        {
            label: 'mti_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-mti',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'mti_slow',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-mti',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'mti_fast',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-mti',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'pcs_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-pcs',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'pcs_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-pcs',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'pcs_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-pcs',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'prs_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-prs',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'prs_close',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-prs',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },


        {
            label: 'rsi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-rsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'rsi_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-rsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'rsi_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-rsi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright pink for RSI line
            borderColor: 'rgb(255, 255, 255)', // Solid bright pink for borders

            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'rsi_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-rsi',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright pink for RSI line
            borderColor: 'rgb(255, 0, 255)', // Solid bright pink for borders

            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'rsi_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-rsi',
            backgroundColor: 'rgba(255, 255,0 , 0.3)', // Bright pink for RSI line
            borderColor: 'rgb(255, 255, 0)', // Solid bright pink for borders

            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'rvi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-rvi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'rvi_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-rvi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'rvi_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-rvi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'rvi_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-rvi',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'sar_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-sar',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'sar_sar',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-sar',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Maintaining bright yellow for SAR bars for consistency and visibility
            borderColor: 'rgb(255, 255, 255)', // Solid bright yellow for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'sar_trend',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-sar',
            backgroundColor: (context: any) => calculateSarTrendBackgroundColor(context),
            borderColor: (context: any) => calculateSarTrendBorderColor(context),
            borderWidth: 1,
            pointRadius: 3,
            fill: true
        },

        {
            label: 'sei_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-sei',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'sei_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-sei',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'sei_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-sei',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'sei_oscillator',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-sei',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'tdsi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-tdsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'tdsi_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-tdsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'tdsi_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-tdsi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'tdsi_upper',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-tdsi',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'tdsi_lower',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-tdsi',
            backgroundColor: 'rgba(255, 255, 0, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 0)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'trix_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trix',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'trix_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trix',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle',
        }, {
            label: 'trix_signal2',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trix',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'rect',
        }, {
            label: 'trix_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-trix',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright orange for TRIX bars, similar to KVO for continuity
            borderColor: 'rgb(255, 255, 255)', // Solid bright orange for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'trix_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-trix',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright orange for TRIX bars, similar to KVO for continuity
            borderColor: 'rgb(255, 0, 255)', // Solid bright orange for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },

        {
            label: 'trsi_signal0',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
        }, {
            label: 'trsi_signal1',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'triangle'
        }, {
            label: 'trsi_signal2',
            type: 'bubble' as const,
            data: [],
            yAxisID: 'y-trsi',
            backgroundColor: (context: any) => calculateSignalBackgroundColor(context),
            borderColor: (context: any) => calculateSignalBorderColor(context),
            pointStyle: 'rect'
        }, {
            label: 'trsi_main',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-trsi',
            backgroundColor: 'rgba(255, 255, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 255, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        }, {
            label: 'trsi_signal',
            type: 'line' as const,
            data: [],
            yAxisID: 'y-trsi',
            backgroundColor: 'rgba(255, 0, 255, 0.3)', // Bright white for KDJ line (for visibility against dark backgrounds)
            borderColor: 'rgb(255, 0, 255)', // Solid bright white for borders
            borderWidth: 1,
            pointRadius: 0,
            fill: false,
        },
    ],
}

export function handleChartMouseMove(event: MouseEvent, chartInstance: Chart, tooltipElement: HTMLDivElement) {
    const points = chartInstance.getElementsAtEventForMode(
        event,
        'nearest' as const,
        { intersect: true },
        false,
    );
    if (points.length) {
        const { datasetIndex, index } = points[0];
        const dataset = chartInstance.data.datasets[datasetIndex];
        const dataPoint = dataset.data[index];

        let content = '';
        if (typeof dataPoint === 'object' && dataPoint !== null) {
            // Exclude the 'age' property
            let dp = { ...dataPoint };
            if ('x' in dp) {
                delete (dp as any).x;
            }
            if ('x' in dataPoint) {
                const jsonString = JSON.stringify(dataPoint, (key, value) => {
                    // Check if the value is a BigInt
                    if (typeof value === 'bigint') {
                        // Convert BigInt to a string
                        return value.toString();
                    }
                    // Return the value unchanged if it's not a BigInt
                    return value;
                });

                content = `${dataset.label}[${index}]: ${formatDate(dataPoint.x)}: ${jsonString}`;
            }
        }
        tooltipElement.textContent = content;
        tooltipElement.style.left = `${event.pageX + 10}px`;
        tooltipElement.style.top = `${event.pageY + 10}px`;
    }
}

export function updateIndicatorChartPart(indicatorChart: Chart, klines: KlineFlat[], idgk: IndicatorGroupKey, yAxisID: string) {
    console.log(`(updateIndicatorChartPart) idgk=${idgk} yAxisID=${yAxisID}`)
    switch (idgk) {
        case 'ADX':
            upsertChartAdx(indicatorChart, klines, yAxisID)
            break
        case 'AROON':
            upsertChartAroon(indicatorChart, klines, yAxisID)
            break
        case 'ASO':
            upsertChartAso(indicatorChart, klines, yAxisID)
            break
        case 'BOLL':
            upsertChartBoll(indicatorChart, klines, yAxisID)
            break
        case 'CCI':
            upsertChartCci(indicatorChart, klines, yAxisID)
            break
        case 'CKO':
            upsertChartCko(indicatorChart, klines, yAxisID)
            break
        case 'CKS':
            upsertChartCks(indicatorChart, klines, yAxisID)
            break
        case 'CMF':
            upsertChartCmf(indicatorChart, klines, yAxisID)
            break
        case 'CMO':
            upsertChartCmo(indicatorChart, klines, yAxisID)
            break
        case 'CPC':
            upsertChartCpc(indicatorChart, klines, yAxisID)
            break
        case 'DCC':
            upsertChartDcc(indicatorChart, klines, yAxisID)
            break
        case 'DPO':
            upsertChartDpo(indicatorChart, klines, yAxisID)
            break
        case 'EFI':
            upsertChartEfi(indicatorChart, klines, yAxisID)
            break
        case 'EOM':
            upsertChartEom(indicatorChart, klines, yAxisID)
            break
        case 'EVL':
            upsertChartEvl(indicatorChart, klines, yAxisID)
            break
        case 'FTF':
            upsertChartFtf(indicatorChart, klines, yAxisID)
            break
        case 'HMA':
            upsertChartHma(indicatorChart, klines, yAxisID)
            break
        case 'IKC':
            upsertChartIkc(indicatorChart, klines, yAxisID)
            break
        case 'KAMA':
            upsertChartKama(indicatorChart, klines, yAxisID)
            break
        case 'KDJ':
            upsertChartKdj(indicatorChart, klines, yAxisID)
            break
        case 'KNC':
            upsertChartKnc(indicatorChart, klines, yAxisID)
            break
        case 'KST':
            upsertChartKst(indicatorChart, klines, yAxisID)
            break
        case 'KVO':
            upsertChartKvo(indicatorChart, klines, yAxisID)
            break
        case 'MACD':
            upsertChartMacd(indicatorChart, klines, yAxisID)
            break
        case 'MFI':
            upsertChartMfi(indicatorChart, klines, yAxisID)
            break
        case 'MTI':
            upsertChartMti(indicatorChart, klines, yAxisID)
            break
        case 'PCS':
            upsertChartPcs(indicatorChart, klines, yAxisID)
            break
        case 'PRS':
            upsertChartPrs(indicatorChart, klines, yAxisID)
            break
        case 'RSI':
            upsertChartRsi(indicatorChart, klines, yAxisID)
            break
        case 'RVI':
            upsertChartRvi(indicatorChart, klines, yAxisID)
            break
        case 'SAR':
            upsertChartSar(indicatorChart, klines, yAxisID)
            break
        case 'SEI':
            upsertChartSei(indicatorChart, klines, yAxisID)
            break
        case 'TDSI':
            upsertChartTdsi(indicatorChart, klines, yAxisID)
            break
        case 'TRIX':
            upsertChartTrix(indicatorChart, klines, yAxisID)
            break
        case 'TRSI':
            upsertChartTrsi(indicatorChart, klines, yAxisID)
            break
    }
}



export function updateMalineChartPart(candleChart: Chart, klines: KlineFlat[], gk: string, period: number, index: number, yAxisID: string) {
    throw new Error('Function not implemented.')
}

export function upsertChartLsma(chart: Chart, klines: KlineFlat[], period: number, index: number, yAxisID: string) {
    // LSMA
    let lsmaData = klines
        .map((kline) => {
            if (kline.map["lsma"]) {
                // console.log(`upsertChartLsma kline.map["lsma"]=`, kline.map["lsma"], ' period=', period)
                return {
                    x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
                    y: getLsmaValueByPeriod(kline.map["lsma"], period),
                }
            } else {
                return null
            }
        })
        .filter(Boolean)

    upsertDataset(chart, GLOBAL_CHART_DATA, `lsma_${index}`, lsmaData, yAxisID)
}

export function upsertChartMa(chart: Chart, klines: KlineFlat[], name: string, period: number, index: number, yAxisID: string) {
    // MA
    let maData = klines
        .map((kline) => {
            if (kline.map[name]) {
                // console.log(`upsertChartMa kline.map[${name}]=`, kline.map[name])

                return {
                    x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
                    y: getMaValueByPeriod(kline.map[name], period),
                }
            } else {
                return null
            }
        })
        .filter(Boolean)

    console.log(`upsertChartMa [${name}] ${period} maData=`, maData)

    upsertDataset(chart, GLOBAL_CHART_DATA, `maline_${index}`, maData, yAxisID)

}



function calculateSarTrendBackgroundColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 

    // if (context.dataIndex >= 6 && context.dataIndex < 10) {
    //     console.log(`(calculateSarTrendColor) dp[${context.dataIndex}]=`, dp)
    // }
    if (dp && dp.y && dp.y > 0) {

        return 'rgba(255, 0, 0, 0.3)';
    } else if (dp && dp.y && dp.y < 0) {

        // if (context.dataIndex == 0) {
        //     console.log("(calculateSarTrendColor) dp=", dp)
        // }
        return 'rgba(0, 255, 0, 0.3)';
    }

    return 'rgba(0, 0, 255, 0.3)';
}

function calculateSarTrendBorderColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 

    // if (context.dataIndex >= 6 && context.dataIndex < 10) {
    //     console.log(`(calculateSarTrendColor) dp[${context.dataIndex}]=`, dp)
    // }
    if (dp && dp.y && dp.y > 0) {

        return 'rgb(255, 0, 0)';
    } else if (dp && dp.y && dp.y < 0) {

        // if (context.dataIndex == 0) {
        //     console.log("(calculateSarTrendColor) dp=", dp)
        // }
        return 'rgb(0, 255, 0)';
    }

    return 'rgb(0, 0, 255)';
}


function calculateSignalBackgroundColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 
    // if (context.dataIndex == 0) {
    //     console.log(`(adx_signal0.backgroundColor) dp.x=${dp.x} dp.y=${dp.y} dp.r=${dp.r} dp.a=${dp.a}`, dp)
    // }
    // Check if 'a' property exists in dp before attempting to access it
    const signal: IndicatorActionWrap | null = (typeof dp === 'object' && dp !== null && 'a' in dp) ? dp.a : null; // Using a ternary operator

    if (signal === null) {
        return 'rgba(0, 0, 0, 0)';
    }
    if (signal.buy > 0) {
        // Assuming a higher number represents a stronger buy signal
        return 'rgba(255, 0, 0, 0.3)';
    } else if (signal.sell > 0) {
        // Assuming a lower negative number represents a stronger sell signal
        return 'rgba(0, 255, 0, 0.3)';
    }

    return 'rgba(0, 0, 0, 0)';
}

function calculateSignalBorderColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 
    const signal: IndicatorActionWrap | null = (typeof dp === 'object' && dp !== null && 'a' in dp) ? dp.a : null; // Using a ternary operator
    if (signal === null) {
        return 'rgba(0, 0, 0, 0)';
    }

    if (signal.buy > 0) {
        return 'rgba(255, 0, 0)';
    } else if (signal.sell > 0) {
        return 'rgba(0, 255, 0)';
    }

    return 'rgba(0, 0, 0, 0)';
}


// Function to access and interpret values from the map
export function getValueByKey(kline: KlineFlat, key: string) {
    const entry = kline.map[key]
    if (!entry) return 0 // Return null if the key doesn't exist

    if ('Float' in entry) {
        return entry.Float // Return the float value
    }

    return 0 // In case of an unexpected structure
}

export function getMaValueByPeriod(wrapper: ValueWrapper, period: number): number | undefined {
    // console.log(`getMaValueByPeriod ${period} wrapper=`, wrapper)
    if ('MaLine' in wrapper) {
        // console.log(`getMaValueByPeriod ${period} wrapper.MaLine=`, wrapper.MaLine)
        const maLine = wrapper.MaLine.find((ma: MAv<number>) => ma.period === period);
        // console.log(`getMaValueByPeriod ${period} maLine=`, maLine)
        return maLine?.value;
    }
    return undefined;
}

export function getLsmaValueByPeriod(wrapper: ValueWrapper, period: number): number | undefined {
    // console.log(`getLsmaValueByPeriod ${period} wrapper=`, wrapper)
    if ('MaLsma' in wrapper) {
        // console.log(`getLsmaValueByPeriod ${period} wrapper.MaLsma=`, wrapper.MaLsma)
        const maLsma = wrapper.MaLsma.find((ma: MAv<LSMAv>) => ma.period === period);
        // console.log(`getLsmaValueByPeriod ${period} maLsma=`, maLsma)
        return maLsma?.value?.b;
    }
    return undefined;
}


export function upsertDataset(chart: Chart, globalChartData: any, label: string, data: any, target_y_axis: string) {
    // console.log('(upsertDataset2) globalChartData=', globalChartData, " chart.data.datasets=", chart.data.datasets)
    // Find the index of the dataset by its label
    const localIndex = chart.data.datasets.findIndex((ds) => ds.label === label)
    const globalIndex = globalChartData.datasets.findIndex((ds: { label: string; }) => ds.label === label)

    if (localIndex !== -1) {
        // Update the data
        chart.data.datasets[localIndex].data = data

        // console.log(
        //     "Dataset with label  '" +
        //     label +
        //     "'  found @ index " +
        //     localIndex +
        //     ' yAxisID=' +
        //     globalChartData.datasets[globalIndex].yAxisID,
        // )
        // Update the chart with the modified data
        // chart.update()
    } else if (globalIndex >= 0) {
        const data_item = globalChartData.datasets[globalIndex]
        data_item.data = data
        data_item.label = label
        data_item.yAxisID = target_y_axis

        // console.log("(upsertDataset) globalIndex >= 0 data_item=", data_item)
        chart.data.datasets.push(data_item)

    }

    // console.log(`target_y_axis=${target_y_axis}`, "chart.data.dataset=", chart.data.datasets, " chart.options.scales=", chart.options.scales)
    chart.update()
}

function calculateSignalStrength(signal: IndicatorActionWrap): number {
    // console.log("calculateSignalStrength signal=", signal);

    if (signal.buy > 0) {
        return Number(signal.buy) / 255 + 3;
    } else if (signal.sell > 0) {
        return Number(signal.sell) / 255 + 3;
    }

    return 0;
}



function getActionByKey(kline: KlineFlat, key: string): IndicatorActionWrap {
    const entry = kline.map[key]
    // console.log(`getActionByKey key=${key} entry=`, entry)
    let none_action: IndicatorActionWrap = { buy: BigInt(0), sell: BigInt(0) };
    if (!entry) return none_action // Return null if the key doesn't exist

    if ('Action' in entry && entry.Action) {
        return entry.Action // Return the action value
    }

    return none_action // In case of an unexpected structure
}

function upsertValue(chart: Chart, klines: KlineFlat[], valueKey: string, yAxisID: string) {
    let values = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: getValueByKey(kline, valueKey),
    }));
    upsertDataset(chart, GLOBAL_CHART_DATA, valueKey, values, yAxisID);
    return values;
}

function upsertValue2(chart: Chart, klines: KlineFlat[], value: number | null, valueKey: string, yAxisID: string) {
    let values = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: value ? value : kline.close,
    }));
    upsertDataset(chart, GLOBAL_CHART_DATA, valueKey, values, yAxisID);
    return values;
}

function upsertSignal(chart: Chart, klines: KlineFlat[], valueKey: string, signalKey: string, yAxisID: string) {
    let signalxs = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: getValueByKey(kline, valueKey),
        r: calculateSignalStrength(getActionByKey(kline, signalKey)),
        a: getActionByKey(kline, signalKey)
    }));
    // console.log(`upsertSignal ${signalKey} signalxs= `, signalxs)
    upsertDataset(chart, GLOBAL_CHART_DATA, signalKey, signalxs, yAxisID);
}

function upsertSignal2(chart: Chart, klines: KlineFlat[], value: number | null, signalKey: string, yAxisID: string) {
    let signalxs = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: value ? value : kline.close,
        r: calculateSignalStrength(getActionByKey(kline, signalKey)),
        a: getActionByKey(kline, signalKey)
    }));
    upsertDataset(chart, GLOBAL_CHART_DATA, signalKey, signalxs, yAxisID);

    return signalxs;
}

export function isInvalidContext(context: any): boolean {
    if (
        context === undefined || context === null ||
        context.chart === undefined || context.chart === null ||
        context.chart.data === undefined || context.chart.data === null
    ) {
        return true;
    }

    const datasets = context.chart.data.datasets;
    if (!Array.isArray(datasets) || context.datasetIndex === undefined) {
        return true;
    }

    const dataset = datasets[context.datasetIndex];
    if (dataset === null || dataset === undefined) {
        return true;
    }

    if (dataset.data === null || dataset.data === undefined) {
        return true;
    }

    // Additional checks to ensure dataIndex is valid within the dataset's data array
    if (context.dataIndex === undefined ||
        !Array.isArray(dataset.data) ||
        context.dataIndex < 0 ||
        context.dataIndex >= dataset.data.length) {
        return true;
    }

    return false;
}

export function calculateVolumeBackgroundColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 
    if (dp.c > dp.o) {
        return 'rgba(255, 0, 0, 0.3)';
    } else if (dp.c < dp.o) {
        return 'rgba(0, 255, 0, 0.3)';
    }
    return 'rgba(0, 0, 0, 0)';
}

export function calculateVolumeBorderColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgb(0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 
    if (dp.c > dp.o) {
        return 'rgb(255, 0, 0)';
    } else if (dp.c < dp.o) {
        return 'rgb(0, 255, 0)';
    }
    return 'rgb(0, 0, 0, 0)';
}

export function calculateTOrderBackgroundColor(context: any): string {
    if (isInvalidContext(context)) {
        return 'rgba(0, 0, 0, 0)';
    }
    const dp = context.chart.data.datasets[context.datasetIndex].data[context.dataIndex]; // Access the datapoint 
    if (dp.order_type === 'BUY') {
        return 'rgb(255, 0, 0)';
    } else {
        return 'rgb(0, 255, 0)';
    }

}



export function formatNumberToString(value: number): string {
    // Convert to string, remove the decimal part, and pad with spaces
    let formattedStr = Math.trunc(value).toString().padStart(4, ' ');

    // Ensure the string does not exceed 4 characters
    return formattedStr.slice(0, 4);
}


export function updateYPriceAxisScale(chart: Chart, prices: FinancialDataPoint[]) {
    // Check if chart options and scales exist, and safely access yAxisID scale
    if (chart.options?.scales?.['y-price']) {
        // Update the scale configuration safely
        chart.options.scales['y-price'] = {
            ...(chart.options.scales['y-price'] ?? {}),
            min: Math.min(...prices.map((candle) => candle.l)) ?? undefined, // Use nullish coalescing to avoid overwriting with undefined
            max: Math.max(...prices.map((candle) => candle.h)) ?? undefined,
        }
    }
}


/**
 * Adjusts the scale of a given y-axis on a Chart.js chart based on the minimum and maximum values 
 * from multiple input valueSets.
 *
 * @param {Chart} chart - The Chart.js instance whose scale is to be adjusted.
 * @param {string} yAxisID - The ID of the y-axis whose scale is to be adjusted.
 * @param {Array<Array<{y: number}>} valueSets - An array of arrays, each containing data points with a numeric 'y' property.
 */
export function updateAxisScale(chart: Chart, yAxisID: string, valueSets: Array<Array<{ y: number }>>): void {
    // Flatten the 'y' values from all valueSets into a single array and compute min/max
    const allValues = valueSets.flatMap(valueSet => valueSet.map(dp => dp.y));
    const minVal = Math.min(...allValues);
    const maxVal = Math.max(...allValues);

    // Check if chart options and scales exist, and safely access yAxisID scale
    if (chart.options?.scales?.[yAxisID]) {
        // Update the scale configuration safely
        chart.options.scales[yAxisID] = {
            ...(chart.options.scales[yAxisID] ?? {}),
            min: minVal ?? undefined, // Use nullish coalescing to avoid overwriting with undefined
            max: maxVal ?? undefined,
        };
    }
}



// Charts for Indicators 
export function upsertChartAdx(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // ADX 
    upsertSignal(chart, klines, 'adx_adx', 'adx_signal0', yAxisID);
    upsertSignal(chart, klines, 'adx_di_plus', 'adx_signal1', yAxisID);


    let adxs = upsertValue(chart, klines, 'adx_adx', yAxisID);
    let di_pluses = upsertValue(chart, klines, 'adx_di_plus', yAxisID);
    let di_minuses = upsertValue(chart, klines, 'adx_di_minus', yAxisID);

    updateAxisScale(chart, yAxisID, [adxs, di_pluses, di_minuses]);


}

export function upsertChartAroon(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // AROON

    upsertSignal(chart, klines, 'aroon_up', 'aroon_signal0', yAxisID);
    upsertSignal(chart, klines, 'aroon_down', 'aroon_signal1', yAxisID);
    upsertSignal(chart, klines, 'aroon_down', 'aroon_signal2', yAxisID);

    let ups = upsertValue(chart, klines, 'aroon_up', yAxisID);

    let downs = upsertValue(chart, klines, 'aroon_down', yAxisID);

    updateAxisScale(chart, yAxisID, [ups, downs]);
}
export function upsertChartAso(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // ASO
    upsertSignal(chart, klines, 'aso_dif', 'aso_signal0', yAxisID);
    upsertSignal(chart, klines, 'aso_dif', 'aso_signal1', yAxisID);


    let difs = upsertValue(chart, klines, 'aso_dif', yAxisID);

    updateAxisScale(chart, yAxisID, [difs]);

}

export function upsertChartBoll(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // Boll
    upsertSignal(chart, klines, 'boll_middle', 'boll_signal0', yAxisID);

    let uppers = upsertValue(chart, klines, 'boll_upper', yAxisID);

    let sources = upsertValue(chart, klines, 'boll_middle', yAxisID);

    let lowers = upsertValue(chart, klines, 'boll_lower', yAxisID);

    updateAxisScale(chart, yAxisID, [uppers, sources, lowers]);
}

export function upsertChartCci(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // CCI
    upsertSignal(chart, klines, 'cci_oscillator', 'cci_signal0', yAxisID);


    let oscillators = upsertValue(chart, klines, 'cci_oscillator', yAxisID);

    updateAxisScale(chart, yAxisID, [oscillators]);

}

export function upsertChartCko(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // CKO 
    upsertSignal(chart, klines, 'cko_oscillator', 'cko_signal0', yAxisID);

    let oscillators = upsertValue(chart, klines, 'cko_oscillator', yAxisID);

    updateAxisScale(chart, yAxisID, [oscillators]);

}
export function upsertChartCks(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    //CKS 
    upsertSignal(chart, klines, 'cks_source', 'cks_signal0', yAxisID);
    upsertSignal(chart, klines, 'cks_stop_long', 'cks_signal1', yAxisID);



    let stop_longs = upsertValue(chart, klines, 'cks_stop_long', yAxisID);

    let sources = upsertValue(chart, klines, 'cks_source', yAxisID);


    let stop_shorts = upsertValue(chart, klines, 'cks_stop_short', yAxisID);

    updateAxisScale(chart, yAxisID, [stop_longs, sources, stop_shorts]);

}
export function upsertChartCmf(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // CMF
    upsertSignal(chart, klines, 'cmf_main', 'cmf_signal0', yAxisID);


    let mains = upsertValue(chart, klines, 'cmf_main', yAxisID);
    updateAxisScale(chart, yAxisID, [mains]);

}
export function upsertChartCmo(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // CMO
    upsertSignal(chart, klines, 'cmo_oscillator', 'cmo_signal0', yAxisID);

    let oscillators = upsertValue(chart, klines, 'cmo_oscillator', yAxisID);

    updateAxisScale(chart, yAxisID, [oscillators]);

}
export function upsertChartCpc(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // CPC 
    upsertSignal(chart, klines, 'cpc_main', 'cpc_signal0', yAxisID);
    upsertSignal(chart, klines, 'cpc_signal', 'cpc_signal1', yAxisID);
    upsertSignal(chart, klines, 'cpc_signal', 'cpc_signal2', yAxisID);

    let mains = upsertValue(chart, klines, 'cpc_main', yAxisID);

    let signals = upsertValue(chart, klines, 'cpc_signal', yAxisID);
    updateAxisScale(chart, yAxisID, [mains, signals]);
}
export function upsertChartDcc(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // DCC
    upsertSignal(chart, klines, 'dcc_middle', 'dcc_signal0', yAxisID);


    let lowers = upsertValue(chart, klines, 'dcc_lower', yAxisID);

    let middles = upsertValue(chart, klines, 'dcc_middle', yAxisID);

    let uppers = upsertValue(chart, klines, 'dcc_upper', yAxisID);
    updateAxisScale(chart, yAxisID, [lowers, middles, uppers]);
}
export function upsertChartDpo(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // DPO
    let dpos = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: getValueByKey(kline, 'dpo_dpo'),
    }))
    upsertDataset(chart, GLOBAL_CHART_DATA, 'dpo_dpo', dpos, yAxisID)

    updateAxisScale(chart, yAxisID, [dpos,]);


}
export function upsertChartEfi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // EFI 

    upsertSignal(chart, klines, 'efi_main', 'efi_signal0', yAxisID);

    let mains = upsertValue(chart, klines, 'efi_main', yAxisID);
    updateAxisScale(chart, yAxisID, [mains]);

}
export function upsertChartEom(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // EOM

    upsertSignal(chart, klines, 'eom_main', 'eom_signal0', yAxisID);

    let mains = upsertValue(chart, klines, 'eom_main', yAxisID);
    updateAxisScale(chart, yAxisID, [mains]);

}
export function upsertChartEvl(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // EVL
    upsertSignal(chart, klines, 'evl_upper', 'evl_signal0', yAxisID);

    let uppers = upsertValue(chart, klines, 'evl_upper', yAxisID);
    let lowers = upsertValue(chart, klines, 'evl_lower', yAxisID);
    let source2s = upsertValue(chart, klines, 'evl_source2', yAxisID);

    updateAxisScale(chart, yAxisID, [uppers, lowers, source2s]);
}
export function upsertChartFtf(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // FTF
    upsertSignal(chart, klines, 'ftf_main', 'ftf_signal0', yAxisID);
    upsertSignal(chart, klines, 'ftf_signal', 'ftf_signal1', yAxisID);

    let mains = upsertValue(chart, klines, 'ftf_main', yAxisID);
    let signals = upsertValue(chart, klines, 'ftf_signal', yAxisID);

    updateAxisScale(chart, yAxisID, [mains, signals,]);
}



// Usage remains the same as in the previous example.
export function upsertChartHma(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // HMA

    upsertSignal(chart, klines, 'hma_hma', 'hma_signal0', yAxisID);

    let hmas = upsertValue(chart, klines, 'hma_hma', yAxisID);

    updateAxisScale(chart, yAxisID, [hmas,]);

}
export function upsertChartIkc(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // IKC
    upsertSignal(chart, klines, 'ikc_tenkan', 'ikc_signal0', yAxisID);
    upsertSignal(chart, klines, 'ikc_kijun', 'ikc_signal1', yAxisID);

    let tenkans = upsertValue(chart, klines, 'ikc_tenkan', yAxisID);
    let kijuns = upsertValue(chart, klines, 'ikc_kijun', yAxisID);
    let spanas = upsertValue(chart, klines, 'ikc_spana', yAxisID);
    let spanbs = upsertValue(chart, klines, 'ikc_spanb', yAxisID);

    updateAxisScale(chart, yAxisID, [tenkans, kijuns, spanas, spanbs]);

}
export function upsertChartKama(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // KAMA
    upsertSignal(chart, klines, 'kama_kama', 'kama_signal0', yAxisID);

    let kamas = upsertValue(chart, klines, 'kama_kama', yAxisID);
    updateAxisScale(chart, yAxisID, [kamas]);
}

export function upsertChartKdj(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // KDJ
    upsertSignal(chart, klines, 'kdj_main', 'kdj_signal0', yAxisID);
    upsertSignal(chart, klines, 'kdj_signal', 'kdj_signal1', yAxisID);
    upsertSignal(chart, klines, 'kdj_main', 'kdj_signal2', yAxisID);

    let mains = upsertValue(chart, klines, 'kdj_main', yAxisID);
    let signals = upsertValue(chart, klines, 'kdj_signal', yAxisID);

    // let value = (Math.min(...mains.map((dp) => dp.y)) + Math.max(...signals.map((dp) => dp.y))) / 2
    // upsertSignal2(chart, klines, value, 'kdj_signal2', yAxisID);

    updateAxisScale(chart, yAxisID, [mains, signals]);

}
export function upsertChartKnc(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // KNC
    upsertSignal(chart, klines, 'knc_upper', 'knc_signal0', yAxisID);

    let uppers = upsertValue(chart, klines, 'knc_upper', yAxisID);

    let sources = upsertValue(chart, klines, 'knc_source', yAxisID);

    let lowers = upsertValue(chart, klines, 'knc_lower', yAxisID);
    updateAxisScale(chart, yAxisID, [uppers, sources, lowers]);

}

export function upsertChartKst(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // Kst
    upsertSignal(chart, klines, 'kst_kst', 'kst_signal0', yAxisID);

    let ksts = upsertValue(chart, klines, 'kst_kst', yAxisID);

    let signals = upsertValue(chart, klines, 'kst_signal', yAxisID);
    updateAxisScale(chart, yAxisID, [ksts, signals]);


}

export function upsertChartKvo(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // KVO
    upsertSignal(chart, klines, 'kvo_main', 'kvo_signal0', yAxisID);
    upsertSignal(chart, klines, 'kvo_signal', 'kvo_signal1', yAxisID);

    let mains = upsertValue(chart, klines, 'kvo_main', yAxisID);

    let signals = upsertValue(chart, klines, 'kvo_signal', yAxisID);

    updateAxisScale(chart, yAxisID, [mains, signals]);
}


export function upsertChartMacd(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    upsertSignal(chart, klines, 'macd_macd', 'macd_signal0', yAxisID);
    upsertSignal(chart, klines, 'macd_signal', 'macd_signal1', yAxisID);


    let mains = upsertValue(chart, klines, 'macd_macd', yAxisID);

    let signals = upsertValue(chart, klines, 'macd_signal', yAxisID);

    let bars = upsertValue(chart, klines, 'macd_bar', yAxisID);

    updateAxisScale(chart, yAxisID, [mains, signals, bars]);

}


export function upsertChartMfi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // MFI

    upsertSignal(chart, klines, 'mfi_upper', 'mfi_signal0', yAxisID);
    upsertSignal(chart, klines, 'mfi_mfi', 'mfi_signal1', yAxisID);

    let uppers = upsertValue(chart, klines, 'mfi_upper', yAxisID);
    let mfis = upsertValue(chart, klines, 'mfi_mfi', yAxisID);
    let lowers = upsertValue(chart, klines, 'mfi_lower', yAxisID);

    updateAxisScale(chart, yAxisID, [uppers, mfis, lowers]);

}


export function upsertChartMti(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // MTI
    upsertSignal(chart, klines, 'mti_slow', 'mti_signal0', yAxisID);

    let slows = upsertValue(chart, klines, 'mti_slow', yAxisID);

    let fasts = upsertValue(chart, klines, 'mfi_fast', yAxisID);
    updateAxisScale(chart, yAxisID, [slows, fasts]);


}


export function upsertChartPcs(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // PCS
    upsertSignal(chart, klines, 'pcs_upper', 'pcs_signal0', yAxisID);

    let uppers = upsertValue(chart, klines, 'pcs_upper', yAxisID);

    let lowers = upsertValue(chart, klines, 'pcs_lower', yAxisID);
    updateAxisScale(chart, yAxisID, [uppers, lowers]);


}

export function upsertChartPrs(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // PRS
    // 这个指标好像没做对，图形看上去没啥用
    let signal0s = upsertSignal2(chart, klines, null, 'prs_signal0', yAxisID);

    let closes = upsertValue2(chart, klines, null, 'prs_close', yAxisID);

    updateAxisScale(chart, yAxisID, [closes]);

}

export function upsertChartRsi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // RSI
    upsertSignal(chart, klines, 'rsi_upper', 'rsi_signal0', yAxisID);
    upsertSignal(chart, klines, 'rsi_main', 'rsi_signal1', yAxisID);

    let uppers = upsertValue(chart, klines, 'rsi_upper', yAxisID);

    let mains = upsertValue(chart, klines, 'rsi_main', yAxisID);


    let lowers = upsertValue(chart, klines, 'rsi_lower', yAxisID);
    updateAxisScale(chart, yAxisID, [uppers, mains, lowers]);

}

export function upsertChartRvi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // RVI
    upsertSignal(chart, klines, 'rvi_main', 'rvi_signal0', yAxisID);
    upsertSignal(chart, klines, 'rvi_signal', 'rvi_signal1', yAxisID);

    let mains = upsertValue(chart, klines, 'rvi_main', yAxisID);

    let signals = upsertValue(chart, klines, 'rvi_signal', yAxisID);
    updateAxisScale(chart, yAxisID, [mains, signals]);


}

export function upsertChartSar(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // SAR 

    upsertSignal(chart, klines, 'sar_sar', 'sar_signal0', yAxisID);

    let sars = upsertValue(chart, klines, 'sar_sar', yAxisID);

    // let trends = klines.map((kline) => ({
    //     x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
    //     y: getValueByKey(kline, 'sar_trend') > 0 ? kline.close / 2 : getValueByKey(kline, 'sar_trend'),
    // }))
    // upsertDataset(chart, GLOBAL_CHART_DATA, 'sar_trend', trends, yAxisID)

    // console.log("(upsertChartSar) trends", trends)

    updateAxisScale(chart, yAxisID, [sars,]);
}

export function upsertChartSei(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // SEI 
    upsertSignal(chart, klines, 'sei_main', 'sei_signal0', yAxisID);

    let mains = upsertValue(chart, klines, 'sei_main', yAxisID);

    let signals = upsertValue(chart, klines, 'sei_signal', yAxisID);

    let oscillators = upsertValue(chart, klines, 'sei_oscillator', yAxisID);
    updateAxisScale(chart, yAxisID, [mains, signals, oscillators]);
}


export function upsertChartTdsi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // TDSI
    upsertSignal(chart, klines, 'tdsi_main', 'tdsi_signal0', yAxisID);
    upsertSignal2(chart, klines, null, 'tdsi_signal1', yAxisID);


    let mains = upsertValue(chart, klines, 'tdsi_main', yAxisID);

    let uppers = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: 0.75,
    }))
    upsertDataset(chart, GLOBAL_CHART_DATA, 'tdsi_upper', uppers, yAxisID)


    let lowers = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: -0.75,
    }))
    upsertDataset(chart, GLOBAL_CHART_DATA, 'tdsi_lower', lowers, yAxisID)

    updateAxisScale(chart, yAxisID, [mains, uppers, lowers]);

}


export function upsertChartTrix(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // TRIX 
    upsertSignal(chart, klines, 'trix_main', 'trix_signal0', yAxisID);
    upsertSignal(chart, klines, 'trix_signal', 'trix_signal1', yAxisID);
    upsertSignal(chart, klines, 'trix_signal', 'trix_signal2', yAxisID);

    let mains = upsertValue(chart, klines, 'trix_main', yAxisID);

    let signals = upsertValue(chart, klines, 'trix_signal', yAxisID);
    updateAxisScale(chart, yAxisID, [mains, signals]);

}

export function upsertChartTrsi(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // TRSI 
    upsertSignal(chart, klines, 'trsi_main', 'trsi_signal0', yAxisID);
    upsertSignal(chart, klines, 'trsi_main', 'trsi_signal1', yAxisID);
    upsertSignal(chart, klines, 'trsi_signal', 'trsi_signal2', yAxisID);


    let mains = upsertValue(chart, klines, 'trsi_main', yAxisID);
    let signals = upsertValue(chart, klines, 'trsi_signal', yAxisID);
    updateAxisScale(chart, yAxisID, [mains, signals]);

}



